﻿/*----------------------------------------------------------------
// Copyright (C) 2011 
// 版权所有。 
//
// 文件名：AbsWebThread.cs
// 文件功能描述：
//
// 
// 创建标识：kenter 2011-10-19
// EMAIL:kenter1643@163.com
//
// 修改标识：
// 修改描述：
//
// 修改标识：
// 修改描述：
//----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections.Concurrent;

namespace WeiBOAPI.Threads
{
    public abstract class AbsWebThread 
        : AbstractThread, IDisposable
    {
        protected Object _lockObj = new Object();
        protected WebClient _webClient = new WebClient();
        protected ManualResetEvent _beginDownEvent;
        protected ConcurrentQueue<string> _wgetQueue = new ConcurrentQueue<string>();

        private static int _timeCount;
        private bool _checkTimeRun = true;
        private Thread _checkTimeOutThread;
        private static readonly int TimeOut = 60*2; //超时
        protected string downUrl = "";

        public AbsWebThread()
        {
            init();
        }

        public WebClient WebClient
        {
            get { return _webClient; }
            set { _webClient = value; }
        }

        public ConcurrentQueue<string> WgetQueue
        {
            get { return _wgetQueue; }
            set { _wgetQueue = value; }
        }

        public void init()
        {
            TimeSel = 10;
            _beginDownEvent = new ManualResetEvent(true);
            _webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler
                    (webClient_DownloadStringCompleted);
            _checkTimeOutThread = new Thread(new ThreadStart(CheckTimeOut));
            _checkTimeOutThread.Start();
        }

        public override void Run()
        {
            try
            {
                if (_wgetQueue.Count > 0 && _beginDownEvent.WaitOne())
                {
                    string url = "";
                    if (!_webClient.IsBusy && _wgetQueue.TryDequeue(out url))
                    {
                        downUrl = url;
                        _webClient.DownloadStringAsync(new Uri(url, UriKind.Absolute));
                        ResetTimeCount();
                        Console.WriteLine("开始读取" + DateTime.Now.ToString("MM:ss:fff"));
                    }

                    _beginDownEvent.Reset();
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
        }

        /// <summary>
        /// 检查超时
        /// </summary>
        public void CheckTimeOut()
        {
            while (_checkTimeRun)
            {
                _timeCount++;
                if (_timeCount > TimeOut)
                {
                    _webClient.CancelAsync();
                    _webClient.Dispose();
                    ResetTimeCount();
                    _beginDownEvent.Set();
                }
                Thread.Sleep(1000);
            }
        }

        public abstract void DownloadFinsh(string msg);

        void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                Console.WriteLine("读取完毕" + DateTime.Now.ToString("MM:ss:fff"));
                DownloadFinsh(e.Result);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                ResetTimeCount();
                _beginDownEvent.Set();
            }
        }

        void ResetTimeCount()
        {
            lock (_lockObj)
            {
                _timeCount = 0;
            }
        }

        public void Dispose()
        {
            _checkTimeRun = false;
            _checkTimeOutThread.Join();
        }

        public override void ExStop(bool shutDown)
        {
            Dispose();
        }
    }
}
